/*
** print_arg.c for strace in /home/seth/System_unix/avance/seutrace
** 
** Made by kevin lansel
** Login   <lansel_k@epitech.net>
** 
** Started on  Wed May  1 16:46:13 2013 kevin lansel
** Last update Fri May 17 17:56:02 2013 kevin lansel
*/

#include	<sys/user.h>
#include	<sys/ptrace.h>
#include	<stdio.h>
#include	<string.h>
#include	"strace.h"

static void	print_int(unsigned long long u, int pid)
{
  char		buff[512];

  (void)pid;
  if (u == 4294967295)
    sprintf(buff, "%s", "-1");
  else
    sprintf(buff, "%lld", u);
  write(1, buff, strlen(buff));
}

static void		print_string(unsigned long long u, int pid)
{
  long			p;

  p = ptrace(PTRACE_PEEKDATA, pid, u, NULL);
  write(1, "\"", 1);
  while (end_str((char *)&p))
    {
      write(1, &p, sizeof(long));
      u = u + 8;
      p = ptrace(PTRACE_PEEKDATA, pid, u, NULL);
    }
  write(1, &p, sizeof(long));
  write(1, "\"", 1);
}

static void		print_ptr(unsigned long long u, int pid)
{
  char		buff[32];

  (void)pid;
  sprintf(buff, "%p", (void *)u);
  write(1, buff, strlen(buff));
}

static t_ptr_func	*gen_tab()
{
  t_ptr_func	*tab;

  tab = xmalloc(8 * sizeof(t_ptr_func));
  tab[0].type = STRING;
  tab[0].func = &print_string;
  tab[1].type = PTR;
  tab[1].func = &print_ptr;
  tab[2].type = INT;
  tab[2].func = &print_int;
  tab[3].type = CHAR;
  tab[3].func = &print_int;
  tab[4].type = LONG;
  tab[4].func = &print_int;
  tab[5].type = U_INT;
  tab[5].func = &print_int;
  tab[6].type = U_CHAR;
  tab[6].func = &print_int;
  tab[7].type = U_LONG;
  tab[7].func = &print_int;
  return (tab);
}

void		loop_ptr_func(unsigned long long *value, t_syscall *sys,
			      struct user_regs_struct *registre, int pid)
{
  int		i;
  int		j;
  t_ptr_func	*ptr;

  i = -1;
  ptr = gen_tab();
  write(1, sys->name, strlen(sys->name));
  write(1, "(", 1);
  while (++i < size_tab(sys->arg))
    {
      if (i != 0)
	write(1, ", ", 2);
      j = -1;
      while (++j < 8)
	if (ptr[j].type == sys->arg[i])
	  ptr[j].func(value[i], pid);
    }
  write(1, ") = ", 4);
  if (sys->value_ret == INT)
    print_int(registre->rax, pid);
  else
    print_ptr(registre->rax, pid);
  write(1, "\n", 1);
}
